home *** CD-ROM | disk | FTP | other *** search
/ Deutsche Edition 1 / Deutsche Edition 1.iso / amok / amok_lha / amok59.lha / AmokEd_V1.02b / txt / EdBlocks.mod < prev    next >
Text File  |  1993-08-15  |  10KB  |  374 lines

  1. (*************************************************************************
  2.  
  3. :Program.    EdBlocks.mod
  4. :Contents.   Routines for Block-Handling for AmokEd
  5. :Author.     Hartmut Goebel
  6. :Language.   Oberon
  7. :Translator. Oberon Compiler V1.17.1
  8. :History.    V0.1 12 Jan 1991 Hartmut Goebel [hG]
  9. :History.    V1.0 14 Apr 1991 [hG]
  10. :History.    V1.1 07 Jul 1991 [hG] +HoldExtPingPong in HoldBlockLines
  11. :Date.       07 Jul 1991 18:37:49
  12.  
  13. *************************************************************************)
  14.  
  15. MODULE EdBlocks;
  16.  
  17. IMPORT
  18.   e: Exec,
  19.   eAD: EdApplDefs,
  20.   edD: EdDisplay,
  21.   edE: EdErrors,
  22.   edG: EdGlobalVars,
  23.   edL: EdLowLevel,
  24.   lst: EdLists,
  25.   ol : OberonLib,
  26.   sys: SYSTEM;
  27.  
  28. CONST
  29.   BlockBegin = "Block Begin";
  30.   BlockEnd = "Block End";
  31.   BlockAlreadyMarked = "Block Already Marked";
  32.   BlockUnmarked = "Block Unmarked";
  33.   BlockNotSpecified = "Block Not Specified";
  34.   CannotMoveIntoSelf = "Cannot Move into self";
  35.   PushmarkStackLimitReached = "pushmark: stack limit reached";
  36.  
  37.   On = TRUE;
  38.   Off = FALSE;
  39.  
  40.  
  41. (* Schaltet Blockanzeige an oder aus (ggf. mit Unblock) *)
  42. PROCEDURE DisplayBlock(on: BOOLEAN);
  43. VAR
  44.   start, lines: INTEGER;
  45.   txt: edG.TextHeaderPtr;
  46. BEGIN
  47.   IF (edG.Block.ENum<0) (* not specified *)
  48.   OR (edG.iconMode IN edG.Block.Owner.status)
  49.   OR (edG.Block.Owner.topLine+edG.Rows<edG.Block.SNum) (* not visible *)
  50.     THEN RETURN; END;
  51.   txt := NIL;
  52.   IF edG.Block.Owner#edG.Text THEN
  53.     txt := edG.Text;
  54.     edD.SwitchEdit(edG.Block.Owner);
  55.   END;
  56.   start := 0;
  57.   IF start < edG.Block.SNum-edG.Text.topLine THEN
  58.     start := SHORT(edG.Block.SNum-edG.Text.topLine) END;
  59.   lines := edG.Rows;
  60.   IF lines > edG.Block.ENum - edG.Block.SNum + 1 THEN
  61.     lines := SHORT(edG.Block.ENum - edG.Block.SNum + 1); END;
  62.   IF NOT on THEN
  63.     edG.Block.SNum := -1; edG.Block.ENum := -1; END;
  64.   edD.TextDisplaySeg(start,lines);
  65.   IF txt#NIL THEN
  66.     edD.SwitchEdit(txt); END;
  67. END DisplayBlock;
  68.  
  69.  
  70. (* Text-Refresh für Block.Owner mit Unblock (nach BDelete/BMove) *)
  71. PROCEDURE RedrawBlockOwner;
  72. VAR
  73.   txt: edG.TextHeaderPtr;
  74. BEGIN
  75.   edG.Block.SNum := -1; edG.Block.ENum := -1;
  76.   IF edG.iconMode IN edG.Block.Owner.status THEN RETURN END;
  77.   txt := NIL;
  78.   IF edG.Block.Owner#edG.Text THEN
  79.     txt := edG.Text; edD.SwitchEdit(edG.Block.Owner); END;
  80.   edD.TextRedisplay;
  81.   IF txt#NIL THEN edD.SwitchEdit(txt); END;
  82. END RedrawBlockOwner;
  83.  
  84.  
  85. PROCEDURE doUnblock*;
  86. BEGIN
  87.   DisplayBlock(Off);
  88. END doUnblock;
  89.  
  90.  
  91. PROCEDURE doBlock*;
  92. BEGIN
  93.   IF (edG.Block.SNum<0) OR (edG.Block.Owner#edG.Text) THEN
  94.     edG.Block.SNum := edG.Text.line;
  95.     lst.SetMark(edG.Block,edG.Text.actLinePtr,NIL);
  96.     edG.Block.Owner := edG.Text;
  97.     edG.Rc := edE.cmdValid2;
  98.     edL.Title(BlockBegin);
  99.   ELSIF edG.Block.ENum<0 THEN
  100.     IF edG.Text.line < edG.Block.SNum THEN
  101.       edG.Block.ENum := edG.Block.SNum;
  102.       edG.Block.SNum := edG.Text.line;
  103.       lst.SetMark(edG.Block,edG.Text.actLinePtr,edG.Block.mark.head);
  104.     ELSE
  105.       edG.Block.ENum := edG.Text.line;
  106.       lst.SetMark(edG.Block,NIL,edG.Text.actLinePtr);
  107.     END;
  108.     DisplayBlock(On); (* nur hier ändert sich die Anzeige *)
  109.     edG.Rc := edE.cmdValid2;
  110.     edL.Title(BlockEnd);
  111.   ELSE
  112.     edG.Rc := edE.cmdFailed; edL.Title(BlockAlreadyMarked);
  113.   END;
  114. END doBlock;
  115.  
  116.  
  117. PROCEDURE BlockSpecified*(): BOOLEAN;
  118. BEGIN
  119.   IF edG.Block.ENum<0 THEN
  120.     edG.Rc := edE.cmdFailed; edL.Title(BlockNotSpecified);
  121.     RETURN FALSE;
  122.   END;
  123.   RETURN TRUE;
  124. END BlockSpecified;
  125.  
  126.  
  127. PROCEDURE NoMoveIntoBlock(): BOOLEAN;
  128. BEGIN
  129.   IF (edG.Text.line>edG.Block.SNum)
  130.   AND (edG.Text.line<=edG.Block.ENum) AND (edG.Block.Owner=edG.Text) THEN
  131.     edG.Rc := edE.cmdFailed; edL.Title(CannotMoveIntoSelf);
  132.     RETURN FALSE;
  133.   END;
  134.   RETURN TRUE;
  135. END NoMoveIntoBlock;
  136.  
  137.  
  138. PROCEDURE RemBlock;
  139. VAR
  140.   NumDelLines: LONGINT;
  141. BEGIN
  142.   INCL(edG.Block.Owner.status,edG.modified);
  143.   IF (edG.Block.Owner.line>=edG.Block.SNum)
  144.   AND (edG.Block.Owner.line<=edG.Block.ENum) THEN
  145.     edG.Block.Owner.actLinePtr := edG.Block.mark.tail.next(edG.Line);
  146.   END;
  147.   edL.FreeLines(edG.Block.Owner.lineList,edG.Block.mark.head,edG.Block.mark.tail);
  148.   NumDelLines := edG.Block.ENum-edG.Block.SNum+1;
  149.   DEC(edG.Block.Owner.numberOfLines,NumDelLines);
  150.   IF edG.Block.Owner.line>edG.Block.SNum THEN
  151.     IF edG.Block.Owner.line <= edG.Block.ENum THEN
  152.       edG.Block.Owner.line := edG.Block.SNum;
  153.     ELSE
  154.       DEC(edG.Block.Owner.line,NumDelLines);
  155.     END;
  156.   END;
  157.   IF edG.Block.Owner.actLinePtr=NIL THEN
  158.     edG.Block.Owner.actLinePtr := edG.Block.Owner.lineList.tail;
  159.   END;
  160. END RemBlock;
  161.  
  162.  
  163. PROCEDURE CopyBlock;
  164. VAR
  165.   Line, NewLine: edG.LinePtr;
  166.   NumMovedLines: LONGINT;
  167.   List: lst.List;
  168. BEGIN
  169.   INCL(edG.Text.status,edG.modified);
  170.   lst.Init(List);
  171.   Line := edG.Block.mark.head(edG.Line);
  172.   LOOP
  173.     NewLine := edL.CreateLineCopy(Line);
  174.     IF NewLine#NIL THEN
  175.       lst.AddTail(List,NewLine);
  176.     ELSE
  177.       IF List.head#NIL THEN
  178.         edL.FreeLines(List,List.head(edG.Line),List.tail(edG.Line)); END;
  179.       edG.Rc := edE.cmdFailed; RETURN;
  180.     END;
  181.     IF Line = edG.Block.mark.tail THEN EXIT; END;
  182.     Line := Line.next(edG.Line);
  183.   END;
  184.   lst.AddMarkBefore(edG.Text.lineList,List,edG.Text.actLinePtr);
  185.   edG.Text.actLinePtr := List.head(edG.Line);
  186.   NumMovedLines := edG.Block.ENum-edG.Block.SNum+1;
  187.   INC(edG.Text.numberOfLines,NumMovedLines);
  188.   IF (edG.Text.line <= edG.Block.SNum) AND (edG.Block.Owner=edG.Text) THEN
  189.     INC(edG.Block.SNum,NumMovedLines);
  190.     INC(edG.Block.ENum,NumMovedLines);
  191.     IF edG.Text.line = edG.Text.topLine THEN
  192.       INC(edG.Text.topLine,NumMovedLines); END;
  193.   END;
  194.   IF edG.Text.line = edG.Text.topLine THEN
  195.     edG.Text.topLinePtr := edG.Text.actLinePtr; END;
  196. END CopyBlock;
  197.  
  198.  
  199. PROCEDURE doBDelete*;
  200. BEGIN
  201.   IF NOT BlockSpecified() THEN RETURN; END;
  202.   edD.PutBackLine;
  203.   RemBlock;
  204.   IF edG.Text.lineList.head=NIL THEN
  205.     edL.NewLine(edG.Text.actLinePtr,edG.ChunkSize); END;
  206.   edD.TextLoad;
  207.   RedrawBlockOwner;
  208. END doBDelete;
  209.  
  210.  
  211. PROCEDURE doBCopy*;
  212. BEGIN
  213.   IF NOT BlockSpecified() OR NOT NoMoveIntoBlock() THEN
  214.     RETURN; END;
  215.   edD.PutBackLine;
  216.   CopyBlock;
  217.   edD.TextLoad;
  218.   edD.TextRedisplay; (* TextSync macht eh' keines *)
  219. END doBCopy;
  220.  
  221.  
  222. PROCEDURE doBMove*;
  223. BEGIN
  224.   IF NOT BlockSpecified() OR NOT NoMoveIntoBlock() THEN
  225.     RETURN; END;
  226.   edD.PutBackLine;
  227.   CopyBlock;
  228.   RemBlock;
  229.   edD.TextLoad;
  230.   RedrawBlockOwner;
  231.   IF edG.Block.Owner#edG.Text THEN edD.TextRedisplay; END;
  232. END doBMove;
  233.  
  234.  
  235. PROCEDURE HoldBlockLines*(Decrement: BOOLEAN);
  236. VAR
  237.   i: INTEGER;
  238. BEGIN
  239.   IF edG.Text.ExtPingPong # NIL THEN
  240.     i := 0;
  241.     REPEAT
  242.       IF edG.Text.ExtPingPong[i].line>edG.Text.line THEN
  243.         IF Decrement THEN
  244.           DEC(edG.Text.ExtPingPong[i].line);
  245.         ELSE
  246.           INC(edG.Text.ExtPingPong[i].line);
  247.         END;
  248.       END;
  249.       INC(i);
  250.     UNTIL i = eAD.NumExtPingPong;
  251.   END;
  252.   IF (edG.Text#edG.Block.Owner) OR (edG.Block.SNum<0)
  253.   OR (edG.Text.line > edG.Block.ENum) THEN
  254.     RETURN;
  255.   END;
  256.   IF (edG.Block.ENum >= 0) THEN
  257.     IF Decrement THEN
  258.       IF (edG.Text.line = edG.Block.ENum) THEN
  259.         IF edG.Block.ENum = edG.Block.SNum THEN
  260.           doUnblock;
  261.           RETURN;
  262.         END;
  263.         edG.Block.mark.head := edG.Block.mark.head.prev;
  264.       END;
  265.       DEC(edG.Block.ENum);
  266.     ELSE
  267.       INC(edG.Block.ENum);
  268.     END;
  269.   END;
  270.   IF edG.Block.SNum >= edG.Text.line THEN
  271.     IF Decrement THEN
  272.       IF (edG.Text.line = edG.Block.SNum) THEN
  273.         edG.Block.mark.head := edG.Block.mark.head.next;
  274.       ELSIF edG.Block.SNum > 0 THEN
  275.         DEC(edG.Block.SNum);
  276.       END;
  277.     ELSIF edG.Block.SNum > edG.Text.line THEN
  278.       INC(edG.Block.SNum);
  279.     END;
  280.   END;
  281. END HoldBlockLines;
  282.  
  283.  
  284. PROCEDURE doBSource*;
  285. VAR
  286.   ThisLine, EndLine: edG.LinePtr;
  287.   Buffer: edG.StringPtr;
  288. BEGIN
  289.   IF NOT BlockSpecified() THEN RETURN; END;
  290.   ol.New(Buffer,edG.MaxLineLength);
  291.   IF Buffer=NIL THEN
  292.     INCL(edG.Status,edG.memoryFail); edG.Rc := edE.cmdSevere;
  293.     RETURN;
  294.   END;
  295.   edD.PutBackLine;
  296.   ThisLine := edG.Block.mark.head(edG.Line);
  297.   EndLine := edG.Block.mark.tail(edG.Line);
  298.   DisplayBlock(Off);
  299.   LOOP
  300.     IF ThisLine=NIL THEN EXIT; END;
  301.     e.CopyMemQuick(ThisLine(edG.Line).string^,Buffer^,edG.MaxLineLength);
  302.     edG.ExecCmd(Buffer);
  303.     IF ThisLine = EndLine THEN EXIT; END;
  304.     ThisLine := ThisLine.next(edG.Line);
  305.   END; (* LOOP *)
  306.   DISPOSE(Buffer);
  307. END doBSource;
  308.  
  309. (*-------------------------------------------------------------------------*)
  310.  
  311.  
  312. PROCEDURE doPushMark*;
  313. BEGIN
  314.   IF BlockSpecified() THEN
  315.     IF edG.BStackCurrDepth = edG.BlockStackSize THEN
  316.       edL.Title(PushmarkStackLimitReached); edG.Rc := edE.cmdFailed;
  317.       RETURN;
  318.     END;
  319.     edG.BStack[edG.BStackCurrDepth] := edG.Block;
  320.     INC(edG.BStackCurrDepth);
  321.     DisplayBlock(Off);
  322.   END;
  323. END doPushMark;
  324.  
  325.  
  326. PROCEDURE doPopMark*;
  327. BEGIN
  328.   edD.PutBackLine;
  329.   DisplayBlock(Off);  (* remove any existing block *)
  330.   IF edG.BStackCurrDepth = 0 THEN (*  no error message on purpose *)
  331.     RETURN;
  332.   END;
  333.   DEC(edG.BStackCurrDepth);
  334.   edG.Block := edG.BStack[edG.BStackCurrDepth];
  335.   IF (edG.Block.Owner = NIL)
  336.   OR (edG.Block.ENum >= edG.Block.Owner.numberOfLines) THEN
  337.     edG.Block.Owner := NIL;
  338.     edG.Block.SNum := -1;
  339.     edG.Block.ENum := -1;
  340.   ELSE
  341.     DisplayBlock(On);
  342.   END;
  343. END doPopMark;
  344.  
  345.  
  346. PROCEDURE doSwapMark*;
  347. VAR
  348.   i: INTEGER;
  349.   tmp: edG.BlockMark;
  350. BEGIN
  351.   doPushMark;
  352.   IF edG.Rc = edE.cmdFailed THEN RETURN; END;
  353.   i := edG.BStackCurrDepth - 2;
  354.   IF i >= 0 THEN
  355.     tmp := edG.BStack[i];
  356.     edG.BStack[i] := edG.BStack[i+1];
  357.     edG.BStack[i+1] := tmp;
  358.   END;
  359.   doPopMark;
  360. END doSwapMark;
  361.  
  362.  
  363. PROCEDURE doPurgeMark*;
  364. BEGIN
  365.   edG.BStackCurrDepth := 0;
  366. END doPurgeMark;
  367.  
  368.  
  369. BEGIN
  370.   edG.Block.SNum := -1; edG.Block.ENum := -1;
  371.   edG.BStackCurrDepth := 0;
  372. END EdBlocks.
  373.  
  374.